<?php
namespace App\Http\Controllers\Api;

use App\Http\Requests\Api\CoachOrdersRequest;
use App\Http\Resources\Api\CoachOrderResource;
use App\Models\Coach;
use App\Models\CoachOrder;
use App\Models\MemberCard;
use App\Models\MemberCardOrder;
use App\Models\Tenant;
use Carbon\Carbon;
use EasyWeChat\Factory;
use Illuminate\Http\Request;
use function EasyWeChat\Kernel\Support\generate_sign;

class CoachOrdersController extends Controller
{
    public function index()
    {
        $user = \Auth::getUser();
        $coach_orders = CoachOrder::with(['coach'])
            ->where([
                'tenant_id' => $user->tenant_id,
                'user_id' => $user->id,
                'is_paid' => true,
            ])->orderByDesc('paid_time')
            ->get();
        return api()->success(CoachOrderResource::collection($coach_orders));
    }

    public function store(CoachOrdersRequest $request)
    {
        $params = $request->only(['code', 'coach_id', 'select_num', 'username', 'phone']);
        $user = \Auth::getUser();
        if (!$user) {
            return api()->failed('用户登录状态已过期，请返回首页重试');
        }
        $user->realname = $params['username'];
        if (!$user->phone) {
            $user->phone = $params['phone'];
        }
        $user->save();

        $coach = Coach::findOrFail($params['coach_id']);
        if ($params['select_num'] < $coach->sale_num) {
            return api()->failed('所选节数不能低于最低起售节数');
        }
        $env = app()->environment();
        // 开发环境支付一分钱
        $total_fee = $env == 'local' ? 0.01 : round($params['select_num'] * $coach->price, 2);
        $auth = $this->mini_program->auth->session($request->code);
        // 如果结果错误，说明 code 已过期或不正确
        if (isset($auth['errcode'])) {
            return api()->failed('code 不正确');
        }
        $coach_order_sn = CoachOrder::generateOrderNo();
        $coach_order = CoachOrder::create([
            'tenant_id' => $this->tenant->id,
            'user_id' => $user->id,
            'coach_id' => $coach->id,
            'order_sn' => $coach_order_sn,
            'sale_num' => $params['select_num'],
            'openid' => $auth['openid'],
            'body' => '购买私教课程',
            'total_fee' => $total_fee,
        ]);
        $unify = [
            'body' => "购买私教课程",
            'out_trade_no' => $coach_order_sn,
            'total_fee' => round($total_fee * 100, 2),
            'trade_type' => 'JSAPI',
            'openid' => $auth['openid'],
            'notify_url' => config('app.url') . '/api/v1/coach_orders/notify', // 单独设置回调地址
        ];
        $result = $this->mini_payment->order->unify($unify);
        if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
            // 二次签名
            $params = [
                'appId' => $this->mini_payment->getConfig()['app_id'],
                'timeStamp' => time() . '',
                'nonceStr' => $result['nonce_str'],
                'package' => 'prepay_id=' . $result['prepay_id'],
                'signType' => 'MD5',
            ];
            $params['paySign'] = generate_sign($params, $this->mini_payment->getConfig()['key']);
            $return['pay_params'] = $params;
            $return['order'] = $coach_order;
            return api()->success($return);
        } else {
            return api()->failed('支付参数错误，请稍后再试');
        }
    }

    public function show($id, Request $request)
    {
        $type = $request->get('type', '');
        $coach_order = CoachOrder::findOrFail($id);
        if ($type == 'pay_status') {
            return api()->success(['is_paid' => $coach_order->is_paid]);
        }
        return api()->success($coach_order);
    }

    public function notify()
    {
        $notify = $this->getNotify();
        $app_id = $notify['appid'];
        \Log::channel('pay_notify')->info('APPID:' . $app_id);
        $tenant = Tenant::where(['md5_weapp_id' => md5($app_id)])->first();
        $mini_payment_config = [
            'app_id' => $tenant->weapp_id,
            'mch_id' => $tenant->mch_id,
            'key' => $tenant->mch_key,
        ];
        $payment = Factory::payment($mini_payment_config);
        $response = $payment->handlePaidNotify(function ($message, $fail) use ($payment) {
            $order_sn = $message['out_trade_no'];
            $coach_order = CoachOrder::where(['order_sn' => $order_sn])->first();
            if ($coach_order->is_paid && $coach_order->paid_time) {
                return true;
            }
            $order_result = $payment->order->queryByOutTradeNumber($order_sn);
            if ($order_result['trade_state'] === 'SUCCESS' && $message['return_code'] === 'SUCCESS' &&
                array_get($message, 'result_code') === 'SUCCESS') {
                $coach_order->is_paid = true;
                $coach_order->paid_time = now();
                $coach_order->transaction_id = $order_result['transaction_id'];
                $coach_order->openid = $order_result['openid'];
//                $coach_order->total_fee = number_format($order_result['total_fee'] / 100, 2);
                $coach_order->save();

                return true;
            } else {
                return $fail('通信失败，请稍后再通知我');
            }
        });
        return $response;
    }
}
